package com.csx.queue;

import com.csx.linkedlist.LinkedList;

/**
 *  链表队列  带有尾指针的链表：使用链表实现队列
 * @author 陈胤训
 * <p>
 * create: 2019-05-05 14:19
 **/
public class linkedListQueue<E> implements Queue<E> {

    private class Node{

        /** 值  */
        public E e;

        /** 下一个节点  */
        public Node next;

        public Node(E e,Node next){
            this.e = e;
            this.next = next;
        }

        public Node(E e){
            this(e,null);
        }

        public Node(){
            this(null,null);
        }

        @Override
        public String toString(){
            return e.toString();
        }
    }

    private Node head, tail;

    private int size;

    public linkedListQueue(){
        head = null;
        tail = null;
        size = 0;
    }
    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void enqueue(E e) {
        if (tail == null){
            tail = new Node(e);
            head = tail;
        }else {
            tail.next = new Node(e);
            tail = tail.next;
        }
        size ++;
    }

    @Override
    public E dequeue() {
        if (isEmpty()){
            throw new IllegalArgumentException("dequeue 方法 . queue 为空 ");
        }
        Node retNode = head;
        head = head.next;
        retNode.next = null;
        if (head == null){
            tail = null;
        }
        size --;
        return retNode.e;
    }

    @Override
    public E getFront() {
        if (isEmpty()){
            throw new IllegalArgumentException("getFront 方法 . queue 为空 ");
        }
        return head.e;
    }

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        res.append("Queue: front");
        for(Node cur = head; cur != null ; cur = cur.next){
            res.append(cur + "->");
        }
        res.append("NULL tail");
        return res.toString();
    }

    public static void main(String[] args) {
        linkedListQueue<Integer> arrayQueue = new linkedListQueue<>();
        for (int i = 0; i < 10 ; i++) {
            arrayQueue.enqueue(i);
            System.out.println(arrayQueue);
            if (i % 3 == 2){
                System.out.println(arrayQueue.dequeue());
            }
        }
    }
}
